3395
12486
HTML에서 배경색으로 입력 할 때 특정 임의의 문자열이 어떻게 색상을 생성합니까? 예를 들면 :
 테스트 
... 모든 브라우저와 플랫폼에서 빨간색 배경의 문서를 생성합니다.
흥미롭게도 chucknorr는 빨간색 배경을 생성하지만 chucknorr는 노란색 배경을 생성합니다.
여기서 무슨 일이 일어나고 있습니까? 
넷스케이프 시대의 이월입니다.
누락 된 숫자는 0 [...]으로 처리됩니다. 잘못된 숫자는 단순히 0으로 해석됩니다. 예를 들어 # F0F0F0, F0F0F0, F0F0F, #FxFxFx 및 FxFxFx 값은 모두 동일합니다.
그것은 다양한 길이의 색상 값 등을 포함하여 매우 자세하게 다루는 Microsoft Internet Explorer의 색상 구문 분석에 대한 블로그 게시물입니다.
블로그 게시물에서 차례로 규칙을 적용하면 다음과 같은 결과가 나타납니다.
유효하지 않은 모든 16 진수 문자를 0으로 바꿉니다.
chucknorris는 c00c0000000이됩니다.
3으로 나눌 수있는 다음 총 문자 수 (11 개 → 12 개)까지 채 웁니다.
c00c 0000 0000
각 구성 요소는 RGB 색상의 해당 색상 구성 요소를 나타내는 세 개의 동일한 그룹으로 분할됩니다.
RGB (c00c, 0000, 0000)
오른쪽에서 두 문자까지 각 인수를 자릅니다.
마지막으로 다음과 같은 결과가 나타납니다.
RGB (c0, 00, 00) = # C00000 또는 RGB (192, 0, 0)
다음은이 "놀라운"색상 견본을 생성하기 위해 bgcolor 속성을 실제로 보여주는 예입니다.
<표>

 척 노리스 
 Mr T 
 닌자 거북이 


 아파 
 쓰레기 
 잔디 


이것은 또한 질문의 다른 부분에 대한 대답입니다. 왜 bgcolor = "chucknorr"가 노란색을 생성합니까? 규칙을 적용하면 문자열은 다음과 같습니다.
c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)]
밝은 노란색 금색을 제공합니다. 문자열이 9 자로 시작하므로 이번에는 두 번째 'C'가 유지되므로 최종 색상 값이됩니다.
나는 원래 누군가가 color = "crap"을 할 수 있다고 지적했을 때 이것을 만났습니다. 그리고 그것은 갈색으로 나옵니다.
|
동의하지 않으셔서 죄송합니다. @Yuhong Bao가 게시 한 레거시 색상 값을 구문 분석하는 규칙에 따르면 chucknorris는 # CC0000과 동일하지 않고 매우 유사하지만 약간 다른 빨간색 색조 인 # C00000과 동일합니다. 이를 확인하기 위해 Firefox ColorZilla 애드온을 사용했습니다.
규칙은 다음과 같이 설명합니다.
0을 추가하여 문자열을 3의 배수로 만듭니다. chucknorris0
문자열을 3 개의 동일한 길이 문자열로 분리합니다. chuc knor ris0
각 문자열을 2 자로 자릅니다. ch kn ri
16 진수 값을 유지하고 필요한 경우 0을 추가합니다. C0 00 00
이 규칙을 사용하여 다음 문자열을 올바르게 해석 할 수있었습니다.
LuckyCharms
운
LuckBeALady
LuckBeALadyTonight
강남 스타일
업데이트 : 색상이 # CC0000이라고 말한 원래 답변자는 이후 수정 사항을 포함하도록 답변을 편집했습니다.
|
대부분의 브라우저는 16 진수가 아닌 숫자를 0으로 대체하여 색상 문자열에서 16 진수가 아닌 값을 무시합니다.
ChuCknorris는 c00c0000000으로 변환됩니다. 이 시점에서 브라우저는 문자열을 빨강, 녹색 및 파랑 값을 나타내는 세 개의 동일한 섹션으로 나눕니다. c00c 0000 0000. 각 섹션의 추가 비트는 무시되어 최종 결과 # c00000이됩니다.
이는 CSS 표준을 따르는 CSS 색상 구문 분석에는 적용되지 않습니다.

빨강

위와 동일

검은 색 | 그 이유는 브라우저가 그것을 이해할 수없고 어떻게 든 그것을 이해할 수있는 것으로,이 경우 16 진수 값으로 변환하려고 시도하기 때문입니다! ... chucknorris는 16 진수로 인식 된 문자 인 c로 시작하며 인식되지 않는 모든 문자를 0으로 변환합니다! 따라서 16 진수 형식의 chucknorris는 다음과 같이됩니다. c00c00000000, 다른 모든 문자는 0이되고 c는 그대로 유지됩니다. 이제 RGB (빨간색, 녹색, 파란색)에 대해 3으로 나뉩니다 ... R : c00c, G : 0000, B : 0000 ... 하지만 우리는 RGB에 유효한 16 진수가 2 자에 불과하다는 것을 알고 있습니다. R : c0, G : 00, B : 00을 의미합니다. 따라서 실제 결과는 다음과 같습니다. bgcolor = "# c00000"; 또한 빠른 참조로 이미지의 단계를 추가했습니다. | 브라우저가 chucknorris를 16 진수 색상 코드로 변환하려고합니다. 유효한 값이 아니기 때문입니다. chucknorris에서 c를 제외한 모든 것은 유효한 16 진수 값이 아닙니다. 따라서 c00c00000000으로 변환됩니다. 빨간색 음영 인 # c00000이됩니다. Chrome (31)과 Firefox (26) 모두이 문제를 무시하므로 Internet Explorer 및 Opera (12)에서 주로 발생하는 문제인 것 같습니다. 추신 괄호 안의 숫자는 내가 테스트 한 브라우저 버전입니다. 더 가벼운 노트 Chuck Norris는 웹 표준을 준수하지 않습니다. 웹 표준 준수 그에게. # 바다 55 | WHATWG HTML 사양에는 레거시 색상을 구문 분석하는 정확한 알고리즘이 있습니다.값: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. 색상 문자열 구문 분석에 사용되는 Netscape Classic 코드는 오픈 소스입니다. https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. 예를 들어, 각 문자는 16 진수로 구문 분석 된 다음 오버플로를 확인하지 않고 32 비트 정수로 시프트됩니다. 8 개의 16 진수 만 32 비트 정수에 들어가기 때문에 마지막 8 자만 고려됩니다. 16 진수를 32 비트 정수로 파싱 한 후 8 비트에 맞을 때까지 16으로 나누어 8 비트 정수로 잘립니다. 이것이 바로 앞의 0이 무시되는 이유입니다. 업데이트 :이 코드는 사양에 정의 된 것과 정확히 일치하지 않지만 몇 줄의 코드 만 다릅니다. 다음 줄이 추가되었다고 생각합니다 (Netscape 4에서). if (bytes_per_val> 4) { bytes_per_val = 4; } | 대답: 브라우저는 chucknorris를 16 진수 값으로 변환하려고 시도합니다. c는 chucknorris에서 유일하게 유효한 16 진수 문자이므로 값은 c00c00000000 (잘못된 모든 값에 대해 0)으로 바뀝니다. 그런 다음 브라우저는 결과를 빨간색 = c00c, 녹색 = 0000, 파란색 = 0000의 3 개 그룹으로 나눕니다. html 배경의 유효한 16 진수 값은 각 색상 유형 (r, g, b)에 대해 2 자리 만 포함하므로 마지막 2 자리는 각 그룹에서 잘리고 rgb 값 c00000은 벽돌-붉은 톤 색상입니다. | chucknorris는 c로 시작하고 브라우저는이를 16 진수 값으로 읽습니다. A, B, C, D, E 및 F는 16 진수 문자이기 때문입니다. 브라우저는 chucknorris를 16 진수 값인 C00C00000000으로 변환합니다. 그런 다음 C00C00000000 16 진수 값이 RGB 형식 (3으로 나눈 값)으로 변환됩니다. C00C00000000 ⇒ R : C00C, G : 0000, B : 0000 브라우저는 색상을 표시하기 위해 두 자리 만 필요합니다. R : C00C, G : 0000, B : 0000 ⇒ R : C0, G : 00, B : 00 ⇒ C00000 마지막으로 웹 브라우저에 bgcolor = C00000을 표시합니다. 다음은이를 보여주는 예입니다. <표> chucknorris c00c00000000 c00000 | 레거시 속성에서 색상을 구문 분석하는 규칙에는 기존 답변에 언급 된 것보다 추가 단계가 포함됩니다. 2 자리 부분으로 자르기 구성 요소는 다음과 같이 설명됩니다. 마지막 8자를 제외한 모든 문자를 버립니다. 모든 구성 요소에 선행 0이있는 한 선행 0을 하나씩 버립니다. 처음 2 개를 제외한 모든 문자를 버립니다. 몇 가지 예 : oooFoooFoooF 000F 000F 000F <-교체, 패드 및 청크 0F 0F 0F <-선행 0이 잘림 0F 0F 0F <-오른쪽에서 2 자로 잘림 oooFooFFoFFF 000F 00FF 0FFF <-교체, 패드 및 청크 00F 0FF FFF <-선행 0이 잘림 00 0F FF <-오른쪽에서 2 자로 잘림 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-교체, 패드 및 청크 BC000000 BC000000 BC000000 <-왼쪽에서 8 자로 잘림 BC BC BC <-오른쪽에서 2 자로 잘림 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-교체, 패드 및 청크 0C000000 0C000000 0C000000 <-왼쪽에서 8 자로 잘림 C000000 C000000 C000000 <-선행 0이 잘림 C0 C0 C0 <-오른쪽에서 2 자로 잘림 다음은 알고리즘의 부분 구현입니다. 사용자가 유효한 색상을 입력하는 오류나 경우는 처리하지 않습니다. function parseColor (input) { // todo : 입력이 ""이면 오류 반환 입력 = input.trim (); // todo : 입력이 "투명"이면 오류 반환 // todo : 입력이 명명 된 색상 인 경우 해당 #rrggbb를 반환합니다. // todo : 입력이 #rgb와 일치하면 #rrggbb를 반환합니다. // todo : U + FFFF보다 큰 유니 코드 코드 포인트를 00으로 대체 if (input.length> 128) { 입력 = input.slice (0, 128); } if (input.charAt (0) === "#") { 입력 = input.slice (1); } 입력 = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length % 3> 0) { 입력 + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0"&& g.charAt (0) === "0"&& b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); b = b.slice (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#"+ r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ( "# input"). on ( "change", function () { var input = $ (this) .val (); var color = parseColor (input); var $ cells = $ ( "# result tbody td"); $ cells.eq (0) .attr ( "bgcolor", input); $ cells.eq (1) .attr ( "bgcolor", color); var값: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. 색상 문자열 구문 분석에 사용되는 Netscape Classic 코드는 오픈 소스입니다. https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. 예를 들어, 각 문자는 16 진수로 구문 분석 된 다음 오버플로를 확인하지 않고 32 비트 정수로 시프트됩니다. 8 개의 16 진수 만 32 비트 정수에 들어가기 때문에 마지막 8 자만 고려됩니다. 16 진수를 32 비트 정수로 파싱 한 후 8 비트에 맞을 때까지 16으로 나누어 8 비트 정수로 잘립니다. 이것이 바로 앞의 0이 무시되는 이유입니다. 업데이트 :이 코드는 사양에 정의 된 것과 정확히 일치하지 않지만 몇 줄의 코드 만 다릅니다. 다음 줄이 추가되었다고 생각합니다 (Netscape 4에서). if (bytes_per_val> 4) { bytes_per_val = 4; } | 대답: 브라우저는 chucknorris를 16 진수 값으로 변환하려고 시도합니다. c는 chucknorris에서 유일하게 유효한 16 진수 문자이므로 값은 c00c00000000 (잘못된 모든 값에 대해 0)으로 바뀝니다. 그런 다음 브라우저는 결과를 빨간색 = c00c, 녹색 = 0000, 파란색 = 0000의 3 개 그룹으로 나눕니다. html 배경의 유효한 16 진수 값은 각 색상 유형 (r, g, b)에 대해 2 자리 만 포함하므로 마지막 2 자리는 각 그룹에서 잘리고 rgb 값 c00000은 벽돌-붉은 톤 색상입니다. | chucknorris는 c로 시작하고 브라우저는이를 16 진수 값으로 읽습니다. A, B, C, D, E 및 F는 16 진수 문자이기 때문입니다. 브라우저는 chucknorris를 16 진수 값인 C00C00000000으로 변환합니다. 그런 다음 C00C00000000 16 진수 값이 RGB 형식 (3으로 나눈 값)으로 변환됩니다. C00C00000000 ⇒ R : C00C, G : 0000, B : 0000 브라우저는 색상을 표시하기 위해 두 자리 만 필요합니다. R : C00C, G : 0000, B : 0000 ⇒ R : C0, G : 00, B : 00 ⇒ C00000 마지막으로 웹 브라우저에 bgcolor = C00000을 표시합니다. 다음은이를 보여주는 예입니다. <표> chucknorris c00c00000000 c00000 | 레거시 속성에서 색상을 구문 분석하는 규칙에는 기존 답변에 언급 된 것보다 추가 단계가 포함됩니다. 2 자리 부분으로 자르기 구성 요소는 다음과 같이 설명됩니다. 마지막 8자를 제외한 모든 문자를 버립니다. 모든 구성 요소에 선행 0이있는 한 선행 0을 하나씩 버립니다. 처음 2 개를 제외한 모든 문자를 버립니다. 몇 가지 예 : oooFoooFoooF 000F 000F 000F <-교체, 패드 및 청크 0F 0F 0F <-선행 0이 잘림 0F 0F 0F <-오른쪽에서 2 자로 잘림 oooFooFFoFFF 000F 00FF 0FFF <-교체, 패드 및 청크 00F 0FF FFF <-선행 0이 잘림 00 0F FF <-오른쪽에서 2 자로 잘림 ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <-교체, 패드 및 청크 BC000000 BC000000 BC000000 <-왼쪽에서 8 자로 잘림 BC BC BC <-오른쪽에서 2 자로 잘림 AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <-교체, 패드 및 청크 0C000000 0C000000 0C000000 <-왼쪽에서 8 자로 잘림 C000000 C000000 C000000 <-선행 0이 잘림 C0 C0 C0 <-오른쪽에서 2 자로 잘림 다음은 알고리즘의 부분 구현입니다. 사용자가 유효한 색상을 입력하는 오류나 경우는 처리하지 않습니다. function parseColor (input) { // todo : 입력이 ""이면 오류 반환 입력 = input.trim (); // todo : 입력이 "투명"이면 오류 반환 // todo : 입력이 명명 된 색상 인 경우 해당 #rrggbb를 반환합니다. // todo : 입력이 #rgb와 일치하면 #rrggbb를 반환합니다. // todo : U + FFFF보다 큰 유니 코드 코드 포인트를 00으로 대체 if (input.length> 128) { 입력 = input.slice (0, 128); } if (input.charAt (0) === "#") { 입력 = input.slice (1); } 입력 = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length % 3> 0) { 입력 + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0"&& g.charAt (0) === "0"&& b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); b = b.slice (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#"+ r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ( "# input"). on ( "change", function () { var input = $ (this) .val (); var color = parseColor (input); var $ cells = $ ( "# result tbody td"); $ cells.eq (0) .attr ( "bgcolor", input); $ cells.eq (1) .attr ( "bgcolor", color); var